use super::{err, err_value, get_dir, json, ok, ECode, Part, Resp, Value};
use base::file::JsonFile;
use bytes::BufMut;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
use tracing::{instrument, warn};

#[instrument(skip_all, name = "do_cmd")]
pub async fn do_cmd(part: &mut Part) -> Resp {
    let _ = save_file(part).await?;
    ok!()
}

#[instrument(skip_all, name = "save_file")]
pub async fn save_file(part: &mut Part) -> Result<String, Value> {
    let name = part.name();

    let fname = part
        .filename()
        .ok_or(err_value(ECode::FileWrite, "no file name"))?;

    let path = format!("{}{}", get_dir(), name);
    let _ = JsonFile::make_dir(&path);

    let path = format!("{}/{}", path, fname);
    warn!("save file: {:?}", &path);

    let mut file = File::create(&path)
        .await
        .or_else(|e| err!(ECode::FileWrite, e))?;

    while let Some(content) = part.data().await {
        let mut tmp: Vec<u8> = Vec::new();
        let content = content.or_else(|e| err!(ECode::FileWrite, e))?;
        tmp.put(content);

        file.write_all(&tmp)
            .await
            .or_else(|e| err!(ECode::FileWrite, e))?;
    }

    file.flush().await.or_else(|e| err!(ECode::FileWrite, e))?;

    Ok(path.to_string())
}
